package cn.lyjuan.archetypes.bms.web.config;

import cn.lyjuan.archetypes.bms.web.cst.SessionConst;
import cn.lyjuan.archetypes.bms.web.util.SessionUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * SpringSecurity 验证码功能
 * 2017.10.1 by chad
 */
public class LoginCodeFilter extends AbstractAuthenticationProcessingFilter
{
    private static Logger log = LogManager.getLogger(LoginCodeFilter.class);

    public static final String LOGIN_CODE_ERROR = "Bad Login Code";
    private String servletPath;

    public LoginCodeFilter(String servletPath, String failureUrl)
    {
        super(servletPath);
        this.servletPath = servletPath;
        // 设置验证失败跳转的地址
        ((SimpleUrlAuthenticationFailureHandler) this.getFailureHandler())
                .setDefaultFailureUrl(failureUrl);
    }


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
    {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        if (log.isDebugEnabled())
            log.debug("method: " + req.getMethod() + " path: " + req.getServletPath());

        if (!"POST".equals(req.getMethod())
                || !this.servletPath.equals(req.getServletPath()))
        {
            chain.doFilter(request, response);
            return;
        }

        String code = req.getParameter("code");
        if (null == code || code.trim().length() < 1)
        {
            unsuccessfulAuthentication(req, resp, new InsufficientAuthenticationException(LOGIN_CODE_ERROR));
            return;
        }

        String sessCode = SessionUtils.get(SessionConst.LOGIN_CODE, String.class);

        if (null == sessCode || !sessCode.equalsIgnoreCase(code))
        {
            unsuccessfulAuthentication(req, resp, new InsufficientAuthenticationException(LOGIN_CODE_ERROR));
            return;
        }

        chain.doFilter(request, response);

        // todo 移除session验证码
        log.info("login code done");
    }

    @Override
    public Authentication attemptAuthentication(
            HttpServletRequest req, HttpServletResponse resp)
            throws AuthenticationException, IOException, ServletException
    {
        return null;
    }


}
